package cn.wolfcode.shop.cloud.web.controller;

import cn.wolfcode.shop.cloud.anno.ValidationAnno;
import cn.wolfcode.shop.cloud.common.BusinessException;
import cn.wolfcode.shop.cloud.common.Result;
import cn.wolfcode.shop.cloud.domain.User;
import cn.wolfcode.shop.cloud.mq.MQCounts;
import cn.wolfcode.shop.cloud.mq.OrderMessage;
import cn.wolfcode.shop.cloud.redis.KeyPrefix;
import cn.wolfcode.shop.cloud.redis.RedisService;
import cn.wolfcode.shop.cloud.service.IOrderInfoService;
import cn.wolfcode.shop.cloud.service.ISeckillOrder;
import cn.wolfcode.shop.cloud.service.ISeckillService;
import cn.wolfcode.shop.cloud.util.GoodCodeMessage;
import cn.wolfcode.shop.cloud.util.SeckillGoodVO;
import cn.wolfcode.shop.cloud.util.SeckillKeyPrefix;
import cn.wolfode.shop.cloud.domain.SeckillOrder;
import com.alibaba.fastjson.JSON;
import org.apache.rocketmq.spring.core.RocketMQTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.websocket.server.PathParam;
import java.util.Date;
import java.util.List;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;

@RestController
public class SeckillOrderController {

    @Autowired
    private ISeckillService seckillService;

    @Autowired
    private ISeckillOrder seckillOrder;

    @Autowired
    private IOrderInfoService orderInfoService;

    @Autowired
    private RedisService redisService;

    @Autowired
    private RocketMQTemplate rocketMQTemplate;

    public static final ConcurrentHashMap<Long,Boolean> isflag = new ConcurrentHashMap<>();


    @RequestMapping("/getPath")
    public Result<String> getPath(String uuid,String verifyCodeResult){
        //判断用户输入的内容是否为空
        if(!StringUtils.hasLength(verifyCodeResult)){
            throw new BusinessException(GoodCodeMessage.SECKILL_VERIFY_EMPTY);
        }
        //从redis中取出验证码表达式的正确结果
        String realVerifyCodeResult = redisService.get(SeckillKeyPrefix.SECKILL_VERIFYCODE, uuid, String.class);
        if(!realVerifyCodeResult.equals(verifyCodeResult)){
            throw new BusinessException(GoodCodeMessage.SECKILL_VERIFY_FAIL);
        }
        //将正确结果与用户输入的结果进行比较
        //生成path
        String path = UUID.randomUUID().toString().replaceAll("-", "");
        redisService.set(SeckillKeyPrefix.SECKILL_PATH,uuid,path);
        return Result.success(path);
    }

    @RequestMapping("/{path}/seckillIOrder")
    public Result<String> seckillIOrder(@PathParam("path") String path, Long seckillId, String uuid, @ValidationAnno User user){
        System.out.println(uuid);
        String resultPath = redisService.get(SeckillKeyPrefix.SECKILL_PATH, uuid, String.class);
        if(resultPath==null){
            throw new BusinessException(GoodCodeMessage.USER_ERROR);
        }
        Long count = 10L;
        //判断用户是否登录，若没登录，提示当前登录用户是非法操作
        if(user==null){
            throw new BusinessException(GoodCodeMessage.USER_ERROR);
        }
        //判断根据秒杀商品的id查询数据库中是否有该数据
        //SeckillGoodVO seckillGoodVO = seckillService.goodDetail(seckillId);
        SeckillGoodVO seckillGoodVO = redisService.hget(SeckillKeyPrefix.SECKILL_GOOD_VO, "", seckillId + "", SeckillGoodVO.class);
        if(seckillGoodVO==null){
            throw new BusinessException(GoodCodeMessage.USER_ERROR);
        }
        //判断当前时间是否处于秒杀状态，若不处于，则提醒用户
        //当当前时间小于开始时间或者当前时间大于结束时间，则不处于秒杀状态
        Date date = new Date();
        if(date.getTime()<seckillGoodVO.getStartDate().getTime()||date.getTime()>seckillGoodVO.getEndDate().getTime()){
            throw new BusinessException(GoodCodeMessage.SECKILL_ERROR);
        }
        //判断用户是否是多次秒杀，若是多次秒杀，提醒用户，您已经秒杀过了
        //SeckillOrder seckillOrder1 = seckillOrder.querySeckillOrder(seckillId,user.getId());
        boolean exists = redisService.exists(SeckillKeyPrefix.SECKILL_GOOD_COUNT, user.getId() + ":" + seckillId);
        if(exists){
            throw new BusinessException(GoodCodeMessage.SECKILLORDER_ERROR);
        }
        //若不存在将重复下单的数据放入redis中
        redisService.set(SeckillKeyPrefix.SECKILL_GOOD_COUNT,user.getId()+":"+seckillId ,"");
        if(isflag.get(seckillId)!=null&&isflag.get(seckillId)){
            throw new BusinessException(GoodCodeMessage.SECKILL_STOCK_ERROR);
        }
        //在redis中做出人数的控制
        count = redisService.dect(SeckillKeyPrefix.SECKILL_REDIS_COUNT, seckillId + "");
        //redisService.hset(SeckillKeyPrefix.SECKILL_GOOD_VO,"",seckillId+"",SeckillGoodVO.class);
        if(count<0){
            isflag.put(seckillId,true);
            throw new BusinessException(GoodCodeMessage.SECKILL_STOCK_ERROR);
        }
        //执行秒杀逻辑
        if(seckillGoodVO.getGoodStock()==0){
            throw new BusinessException(GoodCodeMessage.SECKILL_STOCK_ERROR);
        }
        //封装消息
        OrderMessage orderMessage = new OrderMessage();
        orderMessage.setSeckillId(seckillId);
        orderMessage.setUserId(user.getId());
        orderMessage.setUuid(uuid);
        //把消息发送到消息中间件中
        rocketMQTemplate.syncSend(MQCounts.CREATE_ORDER_DEST,orderMessage);
        //String orderNo = orderInfoService.doSeckillOrder(seckillId, user.getId());
        return Result.success("正在秒杀中...");
    }

    @RequestMapping("/initData")
    public Result initData(){
        List<SeckillGoodVO> seckillGoodVOS = seckillService.query();
        for(SeckillGoodVO seckillGoodVO:seckillGoodVOS){
            //进行redis的初始化库存
            redisService.set(SeckillKeyPrefix.SECKILL_REDIS_COUNT,seckillGoodVO.getId()+"",seckillGoodVO.getGoodStock());
            redisService.hset(SeckillKeyPrefix.SECKILL_GOOD_VO,"",seckillGoodVO.getId()+"", seckillGoodVO);
        }
        return Result.success("初始化成功");
    }
}